package com.wencai.util;

import com.wencai.bean.BuyStock;
import com.wencai.bean.CalculateResult;
import org.jetbrains.annotations.NotNull;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wangpan
 * @date 2023/6/3
 */
public class TimeLoopUtils {
    public static void main(String[] args) {
        List<String> timeLoop = getTimeLoop(15, 00);
        System.out.println(timeLoop);
    }

    public static List<String> getTimeLoop(int startHour,int startMinutes) {
        LocalTime startTime = LocalTime.of(startHour, startMinutes);
        LocalTime endTime = LocalTime.of(15, 5);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHmm");
        List<String> timeLoop = new ArrayList<>();
        while (startTime.isBefore(endTime)) {
            if (!(startTime.isAfter(LocalTime.of(11, 30)) && startTime.isBefore(LocalTime.of(13, 5)))) {
                timeLoop.add(startTime.format(formatter));
            }
            startTime = startTime.plusMinutes(5);
        }
        return timeLoop;
    }


    @NotNull
    public static CalculateResult getCalculateResult(String startTime, String endTime, List<BuyStock> buyList) {
        double totalGainRate = getTotalGainList(buyList);
        double winCount = buyList.stream().filter(item -> item.getGainRate() > 0).count();
        double failCount = buyList.stream().filter(item -> item.getGainRate() < 0).count();
        double winMoreCount = buyList.stream().filter(item -> item.getGainRate() > 0.07).count();
        double failMoreCount = buyList.stream().filter(item -> item.getGainRate() < -0.05).count();
        double winMuchMoreCount = buyList.stream().filter(item -> item.getGainRate() > 0.11).count();
        double failMuchMoreCount = buyList.stream().filter(item -> item.getGainRate() < -0.07).count();
        double maxWin = buyList.stream().mapToDouble(BuyStock::getGainRate).max().orElse(0);
        double maxFail = buyList.stream().mapToDouble(BuyStock::getGainRate).min().orElse(0);
        double averageRate = Math.pow(totalGainRate, 1 / (double) buyList.size());
        CalculateResult result = new CalculateResult(startTime, endTime, totalGainRate);
        result.setWinCount(winCount);
        result.setFailCount(failCount);
        result.setWinMoreCount(winMoreCount);
        result.setWinMuchMoreCount(winMuchMoreCount);
        result.setFailMoreCount(failMoreCount);
        result.setFailMuchMoreCount(failMuchMoreCount);
        result.setMaxWin(maxWin);
        result.setMaxFail(maxFail);
        result.setWinRate(winCount / (winCount + failCount));
        result.setAverageRate(averageRate);
        return result;
    }


    private static double getTotalGainList(List<BuyStock> gainList) {
        double i = 1;
        for (BuyStock buyStock : gainList) {
            i *= 1 + buyStock.getGainRate();

        }
        return i;
    }
}
